package com.yzs.base.utils

import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.os.Looper
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.bumptech.glide.Glide
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.Transformation
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.yzs.base.GlideApp
import com.yzs.base.GlideOptions
import com.yzs.base.GlideRequests

/**
 * yzs
 * 12/18/20.
 * 图片加载 ImageLoader
 */


// 单例实现
object ImageLoader {

    // region 加载圆形图片
    /**
     * 加载圆形图片 { 中心裁剪后做圆形 }
     * [iv] ImageView
     * [any] 图片url res file ...
     * [placeholder] 预加载占位图
     * [error] 加载错误占位图
     * [centerCrop] 中心裁剪
     * [circleCrop] 圆形
     * [skipMemory] 是否跳过内存缓存
     * [strategy] 指定缓存方式
     * [width] 宽
     * [height]高
     */
    @JvmOverloads
    fun loadCircleImage(
        fragmentActivity: FragmentActivity?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        centerCrop: Boolean = true,
        circleCrop: Boolean = true,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        width: Int = -1,
        height: Int = -1
    ) {
        if (fragmentActivity == null || fragmentActivity.isFinishing || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(fragmentActivity)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests?.load(any)?.apply(
            buildGlideOptions(
                centerCrop,
                circleCrop,
                width,
                height,
                skipMemory,
                strategy,
                placeholder,
                error
            )
        )?.into(iv)
    }

    @JvmOverloads
    fun loadCircleImage(
        activity: Activity?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        centerCrop: Boolean = true,
        circleCrop: Boolean = true,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        width: Int = -1,
        height: Int = -1
    ) {
        if (activity == null || activity.isFinishing || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(activity)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests?.load(any)?.apply(
            buildGlideOptions(
                centerCrop,
                circleCrop,
                width,
                height,
                skipMemory,
                strategy,
                placeholder,
                error
            )
        )?.into(iv)
    }

    @JvmOverloads
    fun loadCircleImage(
        fragment: Fragment?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        centerCrop: Boolean = true,
        circleCrop: Boolean = true,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        width: Int = -1,
        height: Int = -1
    ) {
        if (fragment == null
//            || fragment.isDetached
            || iv == null
        ) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(fragment)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests?.load(any)?.apply(
            buildGlideOptions(
                centerCrop,
                circleCrop,
                width,
                height,
                skipMemory,
                strategy,
                placeholder,
                error
            )
        )?.into(iv)
    }

    @JvmOverloads
    fun loadCircleImage(
        context: Context?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        centerCrop: Boolean = true,
        circleCrop: Boolean = true,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        width: Int = -1,
        height: Int = -1
    ) {
        if (context == null || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(context)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests?.load(any)?.apply(
            buildGlideOptions(
                centerCrop,
                circleCrop,
                width,
                height,
                skipMemory,
                strategy,
                placeholder,
                error
            )
        )?.into(iv)
    }


    // endregion

    // region 加载图片
    /**
     * 加载图片
     * [iv] ImageView
     * [any] 图片url res file ...
     * [placeholder] 预加载占位图
     * [error] 加载错误占位图
     * [skipMemory] 是否跳过内存缓存
     * [strategy] 缓存方式
     * [width] 宽
     * [height]高
     */
    @JvmOverloads
    fun loadImage(
        fragmentActivity: FragmentActivity?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        width: Int = -1,
        height: Int = -1,
    ) {
        if (fragmentActivity == null || fragmentActivity.isFinishing || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(fragmentActivity)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests?.load(any)?.apply(
            buildGlideOptions(
                skipMemory = skipMemory,
                strategy = strategy,
                width = width,
                height = height,
                placeholder = placeholder,
                error = error
            )
        )?.into(iv)
    }

    @JvmOverloads
    fun loadImage(
        activity: Activity?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        width: Int = -1,
        height: Int = -1
    ) {
        if (activity == null || activity.isFinishing || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(activity)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests?.load(any)?.apply(
            buildGlideOptions(
                skipMemory = skipMemory,
                strategy = strategy,
                width = width,
                height = height,
                placeholder = placeholder,
                error = error
            )
        )?.into(iv)
    }

    @JvmOverloads
    fun loadImage(
        fragment: Fragment?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        width: Int = -1,
        height: Int = -1
    ) {
        if (fragment == null
//            || fragment.isDetached
            || iv == null
        ) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(fragment)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests?.load(any)?.apply(
            buildGlideOptions(
                skipMemory = skipMemory,
                strategy = strategy,
                width = width,
                height = height,
                placeholder = placeholder,
                error = error
            )
        )?.into(iv)
    }

    @JvmOverloads
    fun loadImage(
        context: Context?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        width: Int = -1,
        height: Int = -1
    ) {
        if (context == null || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(context)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests?.load(any)?.apply(
            buildGlideOptions(
                skipMemory = skipMemory,
                strategy = strategy,
                width = width,
                height = height,
                placeholder = placeholder,
                error = error
            )
        )?.into(iv)
    }

    // endregion

    /**
     * 加载GIF
     * [iv] ImageView
     * [any] 图片url res file ...
     * [placeholder] 预加载占位图
     * [error] 加载错误占位图
     * [skipMemory] 是否跳过内存缓存
     * [strategy] 缓存方式
     */
    fun loadGIFImage(
        fragmentActivity: FragmentActivity?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL
    ) {
        if (fragmentActivity == null || fragmentActivity.isFinishing || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(fragmentActivity)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests
            ?.asGif()
            ?.load(any)
            ?.skipMemoryCache(skipMemory)
            ?.diskCacheStrategy(if (skipMemory) DiskCacheStrategy.NONE else strategy)
            ?.placeholder(placeholder)
            ?.error(error)
            ?.into(iv)
    }

    fun loadGIFImage(
        activity: Activity?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL
    ) {
        if (activity == null || activity.isFinishing || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(activity)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests
            ?.asGif()
            ?.load(any)
            ?.skipMemoryCache(skipMemory)
            ?.diskCacheStrategy(if (skipMemory) DiskCacheStrategy.NONE else strategy)
            ?.placeholder(placeholder)
            ?.error(error)
            ?.into(iv)
    }

    fun loadGIFImage(
        fragment: Fragment?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL
    ) {
        if (fragment == null
//            || fragment.isDetached
            || iv == null
        ) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(fragment)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests
            ?.asGif()
            ?.load(any)
            ?.skipMemoryCache(skipMemory)
            ?.diskCacheStrategy(if (skipMemory) DiskCacheStrategy.NONE else strategy)
            ?.placeholder(placeholder)
            ?.error(error)
            ?.into(iv)
    }

    fun loadGIFImage(
        context: Context?,
        iv: ImageView?,
        any: Any?,
        placeholder: Int = 0,
        error: Int = 0,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL
    ) {
        if (context == null || iv == null) return
        val glideRequests: GlideRequests? = try {
            GlideApp.with(context)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
        glideRequests
            ?.asGif()
            ?.load(any)
            ?.skipMemoryCache(skipMemory)
            ?.diskCacheStrategy(if (skipMemory) DiskCacheStrategy.NONE else strategy)
            ?.placeholder(placeholder)
            ?.error(error)
            ?.into(iv)
    }

    private fun buildGlideOptions(
        centerCrop: Boolean = false,
        circleCrop: Boolean = false,
        width: Int = -1,
        height: Int = -1,
        skipMemory: Boolean = true,
        strategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
        placeholder: Int = 0,
        error: Int = 0
    ): GlideOptions {
        return GlideOptions().apply {
            skipMemoryCache(skipMemory)
            diskCacheStrategy(if (skipMemory) DiskCacheStrategy.NONE else strategy)
            if (width != -1 && width != -1) override(width, height)
            if (placeholder != 0) placeholder(placeholder)
            if (error != 0) error(error)
            if (centerCrop || circleCrop) {
                val multi = mutableListOf<Transformation<Bitmap>>()
                if (centerCrop) multi.add(CenterCrop())
                if (circleCrop) multi.add(CircleCrop())
                if (multi.size > 0) {
                    apply(GlideOptions.bitmapTransform(MultiTransformation(multi)))
                }
            }
        }
    }

    fun clearMemory(context: Context?) {
        if (context == null) return
        if (Looper.getMainLooper() != Looper.myLooper()) return
        Glide.get(context).clearMemory()
    }
}